package beans;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.CloseEvent;

import daos.AlumnoDAO;
import daos.EvaluacionDAO;
import daos.ExamenDAO;
import daos.MatriculaDAO;
import daos.RespuestaDAO;
import daosimp.AlumnoDAOIMP;
import daosimp.EvaluacionDAOIMP;
import daosimp.ExamenDAOIMP;
import daosimp.MatriculaDAOIMP;
import daosimp.RespuestaDAOIMP;
import modelo.Alumno;
import modelo.Cursoperiodo;
import modelo.Evaluacion;
import modelo.Examen;
import modelo.Matricula;
import modelo.Pregunta;
import modelo.Respuesta;
import modelo.Tematica;

@ManagedBean
@RequestScoped
public class ExamenBean {

	private Alumno alumno = (Alumno) FacesContext.getCurrentInstance()
			.getExternalContext().getSessionMap().get("alumno");
	private AlumnoDAO alumnoDAO = new AlumnoDAOIMP();
	private EvaluacionDAO evaluacionDAO = new EvaluacionDAOIMP();
	private RespuestaDAO respuestaDAO = new RespuestaDAOIMP();
	private ExamenDAO examenDAO = new ExamenDAOIMP();
	private Matricula matricula = (Matricula) FacesContext.getCurrentInstance()
			.getExternalContext().getSessionMap().get("matriculaSelec");
	private Examen examen;
	private Date horaActual;
	private Evaluacion evaluacion = evaluacionDAO
			.obtenerEvaluacionVigentexCurso(matricula.getCursoperiodogrupo());
	private List<Pregunta> preguntas = (List<Pregunta>) FacesContext
			.getCurrentInstance().getExternalContext().getSessionMap()
			.get("listaPreguntas");
	private List<Integer> respuestas = (List<Integer>) FacesContext
			.getCurrentInstance().getExternalContext().getSessionMap()
			.get("listaRespuestas");
	private String enunciado, alt1, alt2, alt3, alt4, alt5, indiceTexto,
			resultado;
	private boolean flagExamen;
	private int indicePregunta;
	private int numRespuesta;

	public void atras(ActionEvent e) {
		preguntas = (List<Pregunta>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaPreguntas");
		respuestas = (List<Integer>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaRespuestas");
		indicePregunta = (Integer) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("indice");
		respuestas.add(indicePregunta - 1, numRespuesta);
		indicePregunta--;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("indice", indicePregunta);
		llenarPreguntaActual();
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("listaRespuestas", respuestas);
	}

	public void llenarDatos() {
		indicePregunta = 1;
		List<Tematica> tematicas = new ArrayList<Tematica>();
		List<Pregunta> pregsTotal = new ArrayList<Pregunta>();
		preguntas = new ArrayList<Pregunta>();
		respuestas = new ArrayList<Integer>(
				evaluacion.getNumPreguntasEvaluacion());
		int facil = 0, medio = 0, dificil = 0;
		Cursoperiodo cursoperiodo = matricula.getCursoperiodogrupo()
				.getCursoperiodo();
		for (Object t : cursoperiodo.getTematicas()) {
			Tematica tm = (Tematica) t;
			tematicas.add(tm);
		}
		for (int i = 0; i < tematicas.size(); i++) {
			for (Object p : tematicas.get(i).getPreguntas()) {
				Pregunta pg = (Pregunta) p;
				pregsTotal.add(pg);

			}
		}
		for (int j = 0; j < evaluacion.getNumPreguntasEvaluacion(); j++) {
			int aleatorio = (int) Math.floor(Math.random() * pregsTotal.size());
			switch (pregsTotal.get(aleatorio).getNivelDificultadPregunta()) {
			case 1:
				if (evaluacion.getNivelFacilEvaluaccion() > facil) {
					preguntas.add(pregsTotal.get(aleatorio));
					facil++;
				} else {
					if (evaluacion.getNivelMedioEvaluacion() > medio
							|| evaluacion.getNivelDificilEvaluacion() > dificil)
						j--;
				}
				break;
			case 2:
				if (evaluacion.getNivelMedioEvaluacion() > medio) {
					preguntas.add(pregsTotal.get(aleatorio));
					medio++;
				} else {
					if (evaluacion.getNivelFacilEvaluaccion() > facil
							|| evaluacion.getNivelDificilEvaluacion() > dificil)
						j--;
				}
				break;
			case 3:
				if (evaluacion.getNivelDificilEvaluacion() > dificil) {
					preguntas.add(pregsTotal.get(aleatorio));
					dificil++;
				} else {
					if (evaluacion.getNivelMedioEvaluacion() > medio
							|| evaluacion.getNivelFacilEvaluaccion() > facil)
						j--;
				}
				break;
			}

		}
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("listaPreguntas", preguntas);
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("indice", indicePregunta);
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("listaRespuestas", respuestas);
		llenarPreguntaActual();
	}

	public void llenarPreguntaActual() {
		List<Respuesta> respActual = new ArrayList<Respuesta>();
		respActual = respuestaDAO.buscarRespuestaCorrectaxPregunta(preguntas
				.get(indicePregunta - 1));
		enunciado = preguntas.get(indicePregunta - 1).getEnunciadoPregunta();
		alt1 = respActual.get(0).getTextoRespuesta();
		alt2 = respActual.get(1).getTextoRespuesta();
		alt3 = respActual.get(2).getTextoRespuesta();
		alt4 = respActual.get(3).getTextoRespuesta();
		alt5 = respActual.get(4).getTextoRespuesta();
		numRespuesta = 0;
		indiceTexto = "PEGUNTA   " + indicePregunta;
	}

	public void handleClose(CloseEvent event) {
		try {
			FacesContext.getCurrentInstance().getExternalContext()
					.redirect("alumnoHome.xhtml");
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	public void siguiente(ActionEvent e) {
		preguntas = (List<Pregunta>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaPreguntas");
		respuestas = (List<Integer>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaRespuestas");
		indicePregunta = (Integer) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("indice");
		respuestas.add(indicePregunta - 1, numRespuesta);
		indicePregunta++;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("indice", indicePregunta);
		llenarPreguntaActual();
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("listaRespuestas", respuestas);
	}

	public void terminarExamen() {
		preguntas = (List<Pregunta>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaPreguntas");
		respuestas = (List<Integer>) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("listaRespuestas");
		respuestas.add(indicePregunta - 1, numRespuesta);
		List<Respuesta> resps = new ArrayList<Respuesta>();
		double correcto = 0, incorrecto = 0, nota = 0;
		for (int i = 0; i < preguntas.size(); i++) {
			resps = respuestaDAO.buscarRespuestaCorrectaxPregunta(preguntas
					.get(i));
			for (int j = 0; j < 5; j++) {
				if (resps.get(j).isFlagRespuesta()) {
					if (respuestas.get(i) == j + 1) {
						correcto = correcto
								+ evaluacion.getPtjCorrectoEvaluacion();
					} else {
						incorrecto = incorrecto
								+ evaluacion.getPtjFalloEvaluacion();
					}
				}
			}
		}
		nota = correcto - incorrecto;
		examen.setNota(nota);
		examenDAO.modificarExamen(examen);
		promediarNota();
		alumno.setFlagRendirExamen(false);
		alumnoDAO.modificarAlumno(alumno);
		resultado = "RESULTADO DE EXAMEN\nNOTA: " + nota;
	}

	public void promediarNota() {
		MatriculaDAO matriculaDAO = new MatriculaDAOIMP();
		double promedio = 0, cont = 0;
		List<Examen> exmsAlu = examenDAO.obtenerExamenesxAlumno(alumno);
		for (int i = 0; i < exmsAlu.size(); i++) {
			cont = cont + exmsAlu.get(i).getNota();
		}
		promedio = cont / exmsAlu.size();
		matricula.setNota(promedio);
		matriculaDAO.modificarMatricula(matricula);
	}

	public boolean validarAtras() {
		indicePregunta = (Integer) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("indice");
		if (indicePregunta <= 1) {
			return true;
		}
		return false;
	}

	public boolean validarSiguiente() {
		indicePregunta = (Integer) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("indice");
		if (indicePregunta >= evaluacion.getNumPreguntasEvaluacion()) {
			return true;
		}
		return false;
	}

	public boolean verificarNoExamen() {
		examen = examenDAO.obtenerExamenxEvaluacion(evaluacion, alumno);
		if (examen != null && !alumno.isFlagRendirExamen())
			return true;
		else
			return false;
	}

	public boolean verificarExamen() {
		if (verificarNoExamen() && !flagExamen) {
			return false;
		} else {
			examen = (Examen) FacesContext.getCurrentInstance()
					.getExternalContext().getSessionMap().get("examen");
			flagExamen = false;
			if (examen != null) {
				evaluacion = evaluacionDAO
						.obtenerEvaluacionVigentexCurso(matricula
								.getCursoperiodogrupo());
				indicePregunta = (Integer) FacesContext.getCurrentInstance()
						.getExternalContext().getSessionMap().get("indice");
				flagExamen = true;
			} else {
				if (matricula != null && alumno != null) {
					evaluacion = evaluacionDAO
							.obtenerEvaluacionVigentexCurso(matricula
									.getCursoperiodogrupo());
					if (evaluacion != null) {
						examen = new Examen();
						examen.setAlumno(alumno);
						examen.setEvaluacion(evaluacion);
						examen.setIdExamen("EXM_"
								+ String.valueOf(examenDAO
										.listarTotalExamenes().size() + 1));
						examen.setNota(0.0);
						examenDAO.registrarExamen(examen);
						alumno.setFlagRendirExamen(true);
						alumnoDAO.modificarAlumno(alumno);
						FacesContext.getCurrentInstance().getExternalContext()
								.getSessionMap().put("examen", examen);
						llenarDatos();
						flagExamen = true;
					} else {
						flagExamen = false;
					}
				} else {
					flagExamen = false;
				}
			}
			return flagExamen;
		}
	}

	public String getAlt1() {
		return alt1;
	}

	public String getAlt2() {
		return alt2;
	}

	public String getAlt3() {
		return alt3;
	}

	public String getAlt4() {
		return alt4;
	}

	public String getAlt5() {
		return alt5;
	}

	public Alumno getAlumno() {
		return alumno;
	}

	public String getEnunciado() {
		return enunciado;
	}

	public Evaluacion getEvaluacion() {
		return evaluacion;
	}

	public Examen getExamen() {
		return examen;
	}

	public Date getHoraActual() {
		return horaActual;
	}

	public int getIndicePregunta() {
		return indicePregunta;
	}

	public String getIndiceTexto() {
		return indiceTexto;
	}

	public int getNumRespuesta() {
		return numRespuesta;
	}

	public List<Pregunta> getPreguntas() {
		return preguntas;
	}

	public void setAlt1(String alt1) {
		this.alt1 = alt1;
	}

	public void setAlt2(String alt2) {
		this.alt2 = alt2;
	}

	public void setAlt3(String alt3) {
		this.alt3 = alt3;
	}

	public void setAlt4(String alt4) {
		this.alt4 = alt4;
	}

	public void setAlt5(String alt5) {
		this.alt5 = alt5;
	}

	public void setAlumno(Alumno alumno) {
		this.alumno = alumno;
	}

	public void setEnunciado(String enunciado) {
		this.enunciado = enunciado;
	}

	public void setEvaluacion(Evaluacion evaluacion) {
		this.evaluacion = evaluacion;
	}

	public void setExamen(Examen examen) {
		this.examen = examen;
	}

	public void setHoraActual(Date horaActual) {
		this.horaActual = horaActual;
	}

	public void setIndicePregunta(int indicePregunta) {
		this.indicePregunta = indicePregunta;
	}

	public void setIndiceTexto(String indiceTexto) {
		this.indiceTexto = indiceTexto;
	}

	public void setNumRespuesta(int numRespuesta) {
		this.numRespuesta = numRespuesta;
	}

	public void setPreguntas(List<Pregunta> preguntas) {
		this.preguntas = preguntas;
	}

	public String getResultado() {
		return resultado;
	}

	public void setResultado(String resultado) {
		this.resultado = resultado;
	}

}
